/**
 * &copy; 2006 NewInstance.it
 */
package it.newinstance.jrainbow.parser;

import it.newinstance.jrainbow.source.TaggedChar;
import it.newinstance.jrainbow.source.TaggedCharIterator;
import it.newinstance.jrainbow.source.TaggedSource;

/**
 * @author Luigi R. Viggiano
 * @version $Id: StateMachine.java 159 2007-11-15 02:33:39Z luigi.viggiano $
 * @param <State>
 *            the State type for the StateMachine
 */
public interface StateMachine<State extends StateMachine<State>> {

    /**
     * Handles a char returning the updated state for the state machine.
     * 
     * @param chr
     *            the char to be parsed
     * @return the updated state for the state machine
     */
    public abstract State handle(TaggedChar chr);

    /**
     * Runner defines the method to run a StateMachine.
     * 
     * @author Luigi R. Viggiano
     * @version $Id: StateMachine.java 159 2007-11-15 02:33:39Z luigi.viggiano $
     */
    public static class Runner {
        /**
         * Takes the initial StateMachine state and runs the StateMachine over
         * the given source.
         * 
         * @param initialState
         *            initial StateMachineState
         * @param source
         *            the input source over which the state machine should be
         *            run
         */
        public static void run(StateMachine<?> initialState, 
                TaggedSource source) {
            StateMachine<?> state = initialState;
            for (TaggedChar chr : new TaggedCharIterator(source))
                state = state.handle(chr);
        }
    }
}
